package cn.edu.nuaa.aadl2.generatorC.template

import org.osate.aadl2.PropertyAssociation
import org.osate.aadl2.impl.NamedValueImpl
import org.osate.aadl2.impl.EnumerationLiteralImpl
import org.osate.aadl2.EnumerationLiteral
import org.osate.aadl2.AbstractNamedValue
import org.eclipse.emf.common.util.EList
import org.osate.aadl2.ProcessImplementation
import org.osate.aadl2.impl.StringLiteralImpl
import org.osate.aadl2.impl.ListValueImpl
import org.osate.aadl2.SubprogramImplementation
import org.osate.aadl2.impl.NumberValueImpl
import org.osate.aadl2.NumberValue
import org.osate.aadl2.impl.ModalPropertyValueImpl
import org.osate.aadl2.impl.IntegerLiteralImpl
import org.osate.aadl2.ListValue
import org.osate.aadl2.Classifier
import org.osate.aadl2.impl.ClassifierValueImpl
import org.osate.aadl2.impl.DataTypeImpl
import org.osate.aadl2.DataType
import org.osate.aadl2.DataImplementation
import cn.edu.nuaa.aadl2.generatorC.utils.SubProgramProperties
import cn.edu.nuaa.aadl2.generatorC.utils.Tools
import cn.edu.nuaa.aadl2.generatorC.utils.FileHelper
import org.osate.aadl2.SystemImplementation
import org.osate.aadl2.Subcomponent

/**
 * 每种构建的属性处理方式暂时不知道是否相似,先分开处理 使用整形数字代表处理不同类型组件的属性
 * 1 subprogram
 * 2 system
 * 3 process
 * 4 thread
 * 5 data
 * 0 默认
 * 
 */

class PropertyTemplate {
    /**
     * 功能：根据系统属性，分区属性，连接（connection）生成一个系统的配置文件core.xml
     * 文件格式：。。。。
     * by qiubao
     */
    
   
    
     
   /**
   * 功能：处理系统属性，转换为分区调度信息
   * by:qiubao
   */
   def static systemproperty(SystemImplementation system)'''
   		«FOR property: system.allPropertyAssociations»
   			
   		
   		«ENDFOR»
   
   
   '''


     /**
      * 功能：处理每个分区的连接，转化为端口
      * by:qiubao
      */
      
    
	/**
	 * 开发新属性之前用这个看看属性
	 */
	def static lookAtProperties(Classifier component)'''
		«IF component.allPropertyAssociations!=null»
			«FOR PropertyAssociation pa : component.allPropertyAssociations»
				«pa.property2Code»
			«ENDFOR»	
		«ENDIF»	
	'''
	
	 /**
	  * 这是个粗糙的属性解析 
	  */
	def static property2Code(PropertyAssociation property) '''
		/**===========================================
			«property.property.namespace.name»::«property.property.name» 
			«property.property.name»
		=============FOR value: property.ownedValues*/
		«FOR value : property.ownedValues»
«««			«value.containingClassifier.fullName»
			«var ownedValue=value.ownedValue»
			«switch ownedValue{
				NamedValueImpl:
					"// NamedValueImpl "+ownedValue.namedValue.parseNamedValue
				StringLiteralImpl:
					"// StringLiteralImpl "+ownedValue.value+"(features...);"
				ListValueImpl:
					"// ListValueImpl "+ownedValue.parseListValue
				default:
					"// default "+ownedValue.toString
			}
			»
		«ENDFOR»
		/**=============ENDFOR=========================*/
	'''
	
	
	
	/**
	 * data构件分别有三个属性需要标记 
	 * Data_Representation data构件表示类型 Array Struct Union 或者基础元素也可以
	 * Base_Type data构件如果表示为集合类型,集合元素的类型 ...?这里为了表达一个数组 相当于在这个list里面多次描述某个类型
	 * Dimension 表示data构建是个多维的数组
	 * 
	 */
	 def static dealWithDataProperties(DataImplementation data)'''
		«IF data.allPropertyAssociations!=null»
			«FOR PropertyAssociation pa : data.allPropertyAssociations»
				«pa.property2Code»
			«ENDFOR»	
		«ENDIF»	
	 '''
	 
	 
	  def static dataProperty(PropertyAssociation property)'''
		«property.property.name» «FOR value : property.ownedValues»
«««			«value.containingClassifier.fullName»
			«var ownedValue=value.ownedValue»
			«switch ownedValue{
				NamedValueImpl:
					"// NamedValueImpl "+ownedValue.namedValue.parseNamedValue
				StringLiteralImpl:
					"// StringLiteralImpl "+ownedValue.value+"(features...);"
				ListValueImpl:
					"// ListValueImpl "+ownedValue.parseListValue
				default:
					"// default "+ownedValue.toString
			}
			»
		«ENDFOR»
		/**=============ENDFOR=========================*/
	 '''
	 //qiubao
	 def static dealwithpropertyset(EList<PropertyAssociation> list){
	 	for(property :list){
	 		switch (property.property.name){
	 			case "Partition_Identifier":{println(property.property.name)}
	 		}
	 	}
	 }
	 
	 
	 
	 
	 
	
	
	
	/**
	 * subcomponent中标准的转换propertis元素过程,开放给subprogramSubcomponent的生成过程
	 * 主要处理三种属性
	 * Source_Language : C Signal JAVA  
	 * Source_Name : 函数名称
	 * Source_Text : 需要引入的函数文件/需要被编译的Signal文件绝对地址
	 */
	 def static dealWithSubprogramProperties(EList<PropertyAssociation> list,SubProgramProperties sp){
	 	for (property : list) {
	 		switch (property.property.name){
	 			case "Source_Language": {
	 				for(value : property.ownedValues){
	 					var ownedValue=value.ownedValue	
						if(ownedValue instanceof ListValueImpl)
							{
								var expression=ownedValue.ownedListElements.get(0)
								if(expression instanceof NamedValueImpl)
									sp.sourceLanguage="Signal"
							}
					}
	 			}
	 			
	 			case "Source_Name": {
	 				for(value : property.ownedValues){
	 					var ownedValue=value.ownedValue	
						if(ownedValue instanceof StringLiteralImpl)
							{
								sp.sourceName = ownedValue.value
							}
					}
	 			}
	 			case "Source_Text": {
	 				for(value : property.ownedValues){
	 					var ownedValue=value.ownedValue	
						if(ownedValue instanceof ListValueImpl)
							{
								var expression=ownedValue.ownedListElements.get(0)
								if(expression instanceof StringLiteralImpl)
									sp.sourceText = expression.value
							}
					}
	 				
	 			}
	 		}
	 	}
	 }
	 
	 
	 

	 
	
	
	/**
	 * 若为source text则返回头文件名,否则返回no
	 * 
	 */
	def static getIncludeOfSubprogram(PropertyAssociation property)'''
		«FOR value : property.ownedValues»
			«var ownedValue=value.ownedValue»
			«IF ownedValue instanceof ListValueImpl»
				«IF (ownedValue.ownedListElements.get(0) instanceof StringLiteralImpl)»
					#include "«((ownedValue.ownedListElements.get(0))as StringLiteralImpl).value.replaceAll(".c",".h")»"
				«ENDIF»
			«ENDIF»
		«ENDFOR»
	'''
	
	/**
	 * 当前针对StringLiteralImpl的处理,在每个property的property.ownedValues的for循环中不断解析 ListValueImpl
	 * */
	def static parseListValue(ListValueImpl value){
		var expression=value.ownedListElements.get(0)
		switch expression{
			StringLiteralImpl:
				return expression.value 
			NamedValueImpl:
				return 	expression.namedValue.parseNamedValue
			ClassifierValueImpl:
				return expression.classifier.parseClassifier
			IntegerLiteralImpl:
				return expression
			default:
				return "//PropertyTemplate.xtend asdasd "+expression.toString+ " " + expression.class
		}
		
	}
	
	def static parseClassifier(Classifier classifier){
		var clazz=classifier
		try {
			var type=(clazz as DataTypeImpl).name
			return type
		} catch (Exception exception) {
			return "Classifier can't be cast to DataTypeImpl . fdafds in PropertyTemplate.xtend !! \n"
		}
	}
	
	def static parseNamedValue(AbstractNamedValue  value) {
		switch value{
			EnumerationLiteral:
				 return value.name
			default:
				return value.class.name
		}
	}
	
	
	def static isSignalPlat(PropertyAssociation property){
		if(property.property.name=="Source_Language")
			for(value : property.ownedValues){
				if(value instanceof ListValue)
					{
						var expression=value.ownedListElements.get(0)
						if(expression instanceof NamedValueImpl)
							return expression.namedValue.parseNamedValue=="Signal"
					}
			}
		return false;
	}
	
	
	/**
	 * 获取平台系统名字标识
	 * */ 
	def static getPName(EList<PropertyAssociation>  properties) {
		
		//property.property.namespace.name
		for(property:properties)
			if(property.property.name=="processType")
				for (value : property.ownedValues) {
					var x=value.ownedValue
					switch(x){
						NamedValueImpl: 
							return x.namedValue.parseNamedValue
						default:
							return x.toString
					}
				}
			else if(property.property.name=="method4call")
				for (value : property.ownedValues) {
					var x=value.ownedValue
					switch(x){
						NamedValueImpl: 
							return x.namedValue.parseNamedValue
						default:
							return x.toString
					}
				}	
			else if(property.property.name=="WdDelay")
				for (value : property.ownedValues) {
					var x=value.ownedValue
					switch(x){
						NamedValueImpl: 
							return x.namedValue.parseNamedValue
						default:
							return x.toString
					}
				}	
		return ""
	}

	def static getDelay(SubprogramImplementation subpro){
		for(p:subpro.allPropertyAssociations)
			if(p.property.name=="WdDelay")
			{
				for(v:p.ownedValues)	
				{
					val k =v.ownedValue
					switch k{
						IntegerLiteralImpl: 
						 	return k.value
					}
				}
			}
		return 100
	}

	/*
	 * 针对wd方式调用的subprogram
	 * 
	 */
	 def static isCalledByWd(SubprogramImplementation subpro){
	 	if(subpro.allPropertyAssociations.getPName=="wdStart")
			return true
		else
			return false
	 }

	 
	/**
	 * 针对vWorks
	 * 
	 */
	def static isVxWorks(ProcessImplementation process){
		if(process.allPropertyAssociations.getPName=="VxWorks")
			return true
		else
			return false
	}
	

	

}
